#include "palette/GplPalette.h"

#include <list>
#include <string>
#include <fstream>

using namespace std;

string Strip(const string& str)
{
    if (str.empty())
        return str;
    auto p1 = str.find_first_not_of(' ');
    auto p2 = str.find_last_not_of(' ') + 1;
    string tmp(str, p1, p2);
    return move(tmp);
}

list<string> SplitWithSpace(const string& str)
{
    if (str.empty())
        return move(list<string>());
    list<string> result;
    string tmp = str;
    size_t pos;
    while (true)
    {
        tmp = Strip(tmp);
        pos = tmp.find(' ');
        if (pos == string::npos)
        {
            result.emplace_back(tmp);
            break;
        }
        result.emplace_back(string(tmp, 0, pos));
        tmp = string(tmp, pos, tmp.length());
    }
    return move(result);
}

template<typename T>
vector<T> ListToVector(const list<T>& in)
{
    vector<T> out;
    out.reserve(in.size());
    for (auto& i : in)
        out.emplace_back(i);
    return move(out);
}

shared_ptr<IPalette> GplPaletteReader::ReadFormFile(const string& file)
{
    ifstream is;
    is.open(file, ios::in);
    list<Color> cl;
    std::string temp;
    while(!is.eof())
    {
        getline(is, temp);
        temp = Strip(temp);
        if (temp.empty())
            continue;
        if (temp == "GIMP Palette")
            continue;
        if (temp[0] == '#')
            continue;
        if (temp.find(": ") != string::npos)
            continue;
        Color c(0, 0, 0, 0);
        auto words = SplitWithSpace(temp);
        if (words.size() != 5)
            continue;
        auto i = words.begin();
        try
        {
            c.r = stoi(*i);
            i++;
            c.g = stoi(*i);
            i++;
            c.b = stoi(*i);
            i++;
            c.a = stoi(*i);
        }
        catch(...)
        {
            continue;
        }
        cl.emplace_back(c);
    }
    return make_shared<Palette>(ListToVector(cl));
}

void GplPaletteWriter::WriteToFile(const string& file, const IPalette &palette)
{
    ofstream os;
    os.open(file, ios::out | ios::trunc);
    os << "GIMP Palette" << endl;
    os <<"Name: Untitled" << endl;
    os <<"Channels: RGBA" << endl;
    os <<"Columns: " << palette.GetLength() << endl;
    for(size_t i = 0; i < palette.GetLength(); i++)
    {
        auto color = palette.GetColor(i);
        os <<
            (int)color.r << " " <<
            (int)color.g << " " <<
            (int)color.b << " " <<
            (int)color.a << " " <<
            "index" << i <<
            endl;
    }
}
